package com.mega.ycy.mixin;

import com.mega.ycy.Yiciyuan_EVENT;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.MovingSoundMinecart;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityMinecart;
import net.minecraft.profiler.Profiler;
import net.minecraft.world.World;
import net.minecraft.world.WorldProvider;
import net.minecraft.world.storage.ISaveHandler;
import net.minecraft.world.storage.WorldInfo;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;

import java.util.Set;

@Mixin(WorldClient.class)
public abstract class ClientWorldMixin extends World {
    @Shadow public Set<Entity> entityList;

    @Shadow public Minecraft mc;

    @Shadow public Set<Entity> entitySpawnQueue;

    protected ClientWorldMixin(ISaveHandler saveHandlerIn, WorldInfo info, WorldProvider providerIn, Profiler profilerIn, boolean client) {
        super(saveHandlerIn, info, providerIn, profilerIn, client);
    }

    @Overwrite
    public boolean spawnEntity(Entity entityIn)
    {
        if (Yiciyuan_EVENT.isDeath(entityIn))
            return false;
        boolean flag = super.spawnEntity(entityIn);
        this.entityList.add(entityIn);

        if (flag)
        {
            if (entityIn instanceof EntityMinecart)
            {
                this.mc.getSoundHandler().playSound(new MovingSoundMinecart((EntityMinecart)entityIn));
            }
        }
        else
        {
            this.entitySpawnQueue.add(entityIn);
        }

        return flag;
    }

    @Overwrite
    public void removeEntity(Entity entityIn)
    {
        if (Yiciyuan_EVENT.isSafe(entityIn))
            return;
        super.removeEntity(entityIn);
        this.entityList.remove(entityIn);
    }

    @Overwrite
    public void onEntityAdded(Entity entityIn)
    {
        if (Yiciyuan_EVENT.isDeath(entityIn))
            return;
        super.onEntityAdded(entityIn);

        if (this.entitySpawnQueue.contains(entityIn))
        {
            this.entitySpawnQueue.remove(entityIn);
        }
    }

    @Overwrite
    public void onEntityRemoved(Entity entityIn)
    {
        if (Yiciyuan_EVENT.isSafe(entityIn))
            return;
        super.onEntityRemoved(entityIn);

        if (this.entityList.contains(entityIn))
        {
            if (entityIn.isEntityAlive())
            {
                this.entitySpawnQueue.add(entityIn);
            }
            else
            {
                this.entityList.remove(entityIn);
            }
        }
    }

    @Overwrite
    public void addEntityToWorld(int entityID, Entity entityToSpawn)
    {
        if (Yiciyuan_EVENT.isDeath(entityToSpawn))
            return;
        Entity entity = this.getEntityByID(entityID);

        if (entity != null)
        {
            this.removeEntity(entity);
        }

        this.entityList.add(entityToSpawn);
        entityToSpawn.setEntityId(entityID);

        if (!this.spawnEntity(entityToSpawn))
        {
            this.entitySpawnQueue.add(entityToSpawn);
        }

        this.entitiesById.addKey(entityID, entityToSpawn);
    }

    @Overwrite
    public Entity removeEntityFromWorld(int entityID)
    {
        Entity entity = this.entitiesById.removeObject(entityID);
        if (Yiciyuan_EVENT.isSafe(entity))
            return entity;
        if (entity != null)
        {
            this.entityList.remove(entity);
            this.removeEntity(entity);
        }

        return entity;
    }
}
